package org.nanotek.lucene;

import java.io.File;
import java.io.Serializable;
import java.util.Date;
import java.util.UUID;

import org.apache.lucene.index.IndexWriter;
import org.nanotek.BaseTask;
import org.nanotek.lucene.index.IndexBaseSet.IndexType;
import org.nanotek.lucene.index.IndexSet;
import org.nanotek.lucene.preference.PreferenceSet;
import org.nanotek.lucene.util.BaseHolder;
import org.nanotek.lucene.util.LuceneIndexHolder;
import org.nanotek.lucene.util.ThreadEvent;
import org.nanotek.lucene.util.ThreadPoolListener;

@SuppressWarnings({ "unused", "serial" })
public class IndexTask<K extends Serializable>  extends BaseTask<IndexTask<K>, K>{

	private K taskId; 
	private PreferenceSet  taskPreferences;
	private ThreadPoolListener executionListener;
	private ThreadGroup localThreadGroup;
	private IndexSet indexSet;
	private String taskName;
	private Date taskDate;

	public IndexTask(){
		taskDate = new Date();
	} 
	
	public IndexTask(K id , PreferenceSet properties , ThreadPoolListener executionListener, IndexSet indexSet) 
	{ 
		taskDate = new Date();
		this.taskId = id;
		this.taskPreferences = properties;
		this.executionListener = executionListener;
		localThreadGroup = new  ThreadGroup("INDEX-TASK " + id);
		this.indexSet = indexSet;
		this.taskName = "IndexTask";
	}

	public ThreadGroup getLocalThreadGroup() {
		return localThreadGroup;
	}

	@Override
	public K call() throws Exception {
		return null;
	}
	
	public void run() {
		try {
			BaseHolder<File,IndexWriter> holder = prepareDocument();
			parseDocument (holder);
		}catch (Exception ex) { 
			ex.printStackTrace();
		}finally { 
			notifyTerminationListeners();
		}
	}

	private void notifyTerminationListeners() {
		executionListener.executed(new ThreadEvent(Thread.currentThread()));
	}

	private BaseHolder<File,IndexWriter> prepareDocument() throws Exception
	{ 
		String fileName = taskPreferences.get("fileName");
		File file = new File(fileName);
		System.out.println("profile_file_" + taskId + " " + file.getPath());
		System.out.println("Task submitted " + taskId.toString() + " " + System.currentTimeMillis());
		UUID uuid = indexSet.createIndexWriter(IndexType.STANDARD);
		return new LuceneIndexHolder(file, uuid , indexSet);
	}

	private  void parseDocument (BaseHolder<File,IndexWriter> holder) throws Exception
	{ 
		File file = new File(taskPreferences.get("fileName"));
		Thread indexThread = new Thread(localThreadGroup , new IndexerTask(holder));
//		localThreadGroup =  indexThread.getThreadGroup();
		indexThread.start();
		indexThread.join();
		return;
	}

	class IndexerTask implements Runnable {

//		private final ArtistNameIndexer indexer;
		private final File targetFile; 
		private final IndexWriter writer;

		IndexerTask (BaseHolder<?,?> holder)
		{ 
			System.out.println("\t Indexer Task");
//			indexer = new ArtistNameIndexer();
			System.err.println(holder.getKey() + " ||| " + holder.getValue());
			targetFile =  (File) holder.getKey(); 
			writer = (IndexWriter) holder.getValue();
		}

		@Override
		public void run() {
			try {
				indexDocument(targetFile,  writer);
				System.out.println(">>>\t IndexDocument Executed: " + Thread.currentThread().getId());
			} catch (Exception e) {
				e.printStackTrace();
			}			
		} 

		public synchronized void indexDocument(File targetFile, IndexWriter writer) throws Exception{
//			indexer.indexDocs(writer, targetFile);
		}
	}

	@Override
	public K getTaskId() {
		return taskId;
	}

	@Override
	public String getTaskName() {
		return taskName;
	}

	@Override
	public Date getTaskDate() {
		return taskDate;
	}
	
	public void setTaskDate(Date taskDate) {
		this.taskDate = taskDate;
	}
	
	@Override
	public K getId() {
		return taskId;
	}
	
	public void setId(K taskId) {
		this.taskId = taskId;
	}

	@Override
	public PreferenceSet getTaskPreferenceSet() {
		return taskPreferences;
	}

	public void setTaskId(K taskId) {
		this.taskId = taskId;
	}

	public void setTaskPreferenceSet(PreferenceSet taskPreferences) {
		this.taskPreferences = taskPreferences;
	}

	public void setTaskName(String taskName) {
		this.taskName = taskName;
	}

}
